package com.cf.web.servlet;
import com.alibaba.fastjson.JSONObject;
import com.cf.dao.WorksDao;
import com.cf.dao.entity.*;
import com.cf.dao.impl.WorksDaoImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@WebServlet(name = "WorksServlet", value = "/works/*")
public class WorksServlet extends HttpServlet {
    private WorksDao worksDao = new WorksDaoImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        String pathInfo = req.getPathInfo();
        if (pathInfo != null) {
            switch (pathInfo) {
                case "/all":
                    try {
                        findWorksScore(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "/categories":
                    findAllCategories(req, res);
                    break;
                case "/category":
                    findworksbyCategory(req, res);
                    break;
                case "/top":
                    findTopWorks(req, res);
                    break;
                case "/negativeworks":
                    try {
                        negativeworks(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "/work":
                    findWorksById(req, res);
                    break;
                case "/attention":
                    try {
                        findAttention(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "/attentionuser":
                    try {
                        findAttentionuser(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "/Moattention":
                    try {
                        Moattentionall(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                case "/addviews":
                    try {
                        addViews(req, res);
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                    break;
                    case "/score":
                        try {
                            findScorebyid(req, res);
                        } catch (SQLException e) {
                            throw new RuntimeException(e);
                        }
                        break;
                        case "/findattentionworks":
                            try {
                                findattentionworks(req, res);
                            } catch (SQLException e) {
                                throw new RuntimeException(e);
                            }
                            break;
                default:
                    res.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid endpoint");
            }
        } else {
            res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing endpoint");
        }
    }
    //所有作品
    private void findAllWorks(HttpServletRequest req, HttpServletResponse res) {
        res.setContentType("application/json;charset=UTF-8");
        try {
            // 获取所有的 works 数据
            List<Works> works = worksDao.Findallworks();
            // 格式化日期字段，假设你希望日期格式为 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
            // 将数据转换成 JSON 格式并返回
            String jsonResponse = objectMapper.writeValueAsString(works);
            res.getWriter().write(jsonResponse);
        } catch (SQLException e) {
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                res.getWriter().write("{\"error\": \"Failed to retrieve works.\"}");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //所有分类
    private void findAllCategories(HttpServletRequest req, HttpServletResponse res) {
        res.setContentType("application/json;charset=UTF-8");
        try {
            // 获取所有分类
            List<Category> categories = worksDao.Findallcategory();

            // 返回 JSON 响应
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonResponse = objectMapper.writeValueAsString(categories);
            res.getWriter().write(jsonResponse);
        } catch (SQLException e) {
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                res.getWriter().write("{\"error\": \"Failed to retrieve categories\"}");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //根据分类id获取作品
    private void findworksbyCategory(HttpServletRequest req, HttpServletResponse res) throws IOException {
        res.setContentType("application/json;charset=UTF-8");
        // 从请求的查询参数中获取 categoryid
        String categoryidParam = req.getParameter("categoryid");
        // 如果 categoryid 参数为空，返回错误
        if (categoryidParam == null || categoryidParam.isEmpty()) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"code\": 400, \"message\": \"Missing or invalid categoryid parameter\"}");
            return;
        }
        try {
            int categoryid = Integer.parseInt(categoryidParam); // 转换为整数
            // 获取分类下的作品
            List<Works> works = worksDao.Findallworksbycategory(categoryid);
            List<Score> scores = worksDao.Findscoreall();
            List<Worksinfo> worksinfos = new ArrayList<>();

            // 整合 works 和 score 数据
            for (Works work : works) {
                for (Score score : scores) {
                    if (work.getWorksid()==score.getWorksid()) {  // 如果作品ID与评分的作品ID匹配
                        Worksinfo worksinfo = new Worksinfo(work, score);
                        worksinfos.add(worksinfo);
                        break; // 找到匹配的评分后跳出循环
                    }
                }
            }
            // 转换为 JSON 并返回
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
            String jsonResponse = objectMapper.writeValueAsString(worksinfos);
            res.getWriter().write(jsonResponse);
        } catch (NumberFormatException e) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"code\": 400, \"message\": \"Invalid categoryid format\"}");
        } catch (SQLException e) {
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            res.getWriter().write("{\"code\": 500, \"message\": \"Failed to retrieve works by category\"}");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //获取所有top作品
    private void findTopWorks(HttpServletRequest req, HttpServletResponse res) throws IOException {
        // 设置响应内容类型为 JSON
        res.setContentType("application/json;charset=UTF-8");
        try {
            // 调用 DAO 获取所有 top works 的详细数据
            List<Works> worksDetails = worksDao.findTopWorksDetails();
            // 使用 Jackson 库将对象转换为 JSON
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonResponse = objectMapper.writeValueAsString(worksDetails);
            // 设置状态码为 200 (OK)，并将 JSON 数据写入响应
            res.setStatus(HttpServletResponse.SC_OK);
            res.getWriter().write(jsonResponse);
        } catch (SQLException e) {
            // 处理数据库查询异常
            e.printStackTrace();
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            res.getWriter().write("{\"error\": \"Failed to fetch works details.\"}");
        }
    }
    //获取所有负面评分作品
    private void negativeworks(HttpServletRequest req, HttpServletResponse res) throws IOException, SQLException {
        res.setContentType("application/json; charset=UTF-8");
        // 获取所有的 works 数据
        List<Works> works = worksDao.Findallworks();
        List<Score> scores = worksDao.Findscoreall();
        List<Worksinfo> worksinfos = new ArrayList<>();
        // 整合 works 和 score 数据
        for (Works work : works) {
            for (Score score : scores) {
                if (work.getId().equals(score.getWorksid())) {  // 如果作品ID与评分的作品ID匹配
                    // 如果评分小于 3，则将其加入返回数据
                    if (score.getScore() != null && Double.parseDouble(score.getScore()) < 3) {
                        Worksinfo worksinfo = new Worksinfo(work, score);
                        worksinfos.add(worksinfo);
                    }
                    break; // 找到匹配的评分后跳出循环
                }
            }
        }
        // 格式化日期字段，假设你希望日期格式为 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
        // 将数据转换成 JSON 格式并返回
        String jsonResponse = objectMapper.writeValueAsString(worksinfos);
        res.getWriter().write(jsonResponse);
    }
    //根据id获取作品
    private void findWorksById(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json; charset=UTF-8");
        JSONObject result = new JSONObject();
        // 获取 id 参数
        String idParam = request.getParameter("id"); // 获取 URL 查询参数
        System.out.println("idParam: " + idParam);
        if (idParam == null || idParam.isEmpty()) {
            result.put("success", false);
            result.put("message", "ID parameter is required.");
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 Bad Request
            response.getWriter().write(result.toJSONString());
            return;
        }
        int id;
        try {
            id = Integer.parseInt(idParam);  // 将参数转换为整型
            System.out.println("id: " + id);
        } catch (NumberFormatException e) {
            result.put("success", false);
            result.put("message", "Invalid ID parameter.");
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 Bad Request
            response.getWriter().write(result.toJSONString());
            return;
        }
        try {
            List<Works> works = worksDao.Findworksbyid(id);  // 确保传递了 id
            if (works == null || works.isEmpty()) {
                result.put("success", false);
                result.put("message", "No works found for the given ID.");
                response.setStatus(HttpServletResponse.SC_NOT_FOUND); // 404 Not Found
            } else {
                result.put("success", true);
                result.put("message", "Query successful.");
                // 创建一个 List 用来存储所有整合后的数据
                List<Map<String, Object>> worksData = new ArrayList<>();
                for (Works work : works) {
                    Map<String, Object> workData = new HashMap<>();
                    // 假设 Works 类中有多个字段
                    workData.put("id", work.getId());  // 示例字段
                    workData.put("title", work.getTitle());  // 示例字段
                    workData.put("categoryid", work.getCategoryid());  // 示例字段
                    workData.put("producer", work.getProducer());
                    workData.put("score", work.getScore());
                    workData.put("date", work.getDate());
                    workData.put("viewcount", work.getViewcount());
                    workData.put("introduction", work.getIntroduction());
                    workData.put("video", work.getVideo());
                    workData.put("commentid", work.getCommentid());
                    workData.put("worksid",work.getWorksid());
                    // 获取并拆分 img 字段为列表
                    String imgField = work.getImg();  // 假设 img 字段为 String 类型
                    if (imgField != null && !imgField.isEmpty()) {
                        List<String> imgList = Arrays.asList(imgField.split(","));
                        workData.put("img", imgList);  // 添加 img 列表
                    }
                    // 你可以继续添加更多的字段到 workData 中
                    worksData.add(workData);  // 将整合后的数据添加到结果列表中
                }
                // 将整合后的数据列表作为 "data" 传递给前端
                result.put("data", worksData);
                response.setStatus(HttpServletResponse.SC_OK); // 200 OK
            }

        } catch (SQLException e) {
            result.put("success", false);
            result.put("message", "Database error occurred.");
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error
            e.printStackTrace();  // 记录错误日志，开发环境可用，生产环境考虑使用日志记录
        }
        // 返回 JSON 响应
        response.getWriter().write(result.toJSONString());
    }
    //获取全部评分
    private void findWorksScore(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException {
        res.setContentType("application/json; charset=UTF-8");

        // 获取所有的 works 数据
        List<Works> works = worksDao.Findallworks();
        List<Score> scores = worksDao.Findscoreall();

        // 创建一个基于 worksid 的 Map 以快速查找 Score 对象
        Map<Integer, Score> scoreMap = new HashMap<>();
        for (Score score : scores) {
            scoreMap.put(score.getWorksid(), score);
        }

        // 整合 works 和 score 数据
        List<Worksinfo> worksinfos = new ArrayList<>();
        for (Works work : works) {
            Score score = scoreMap.get(work.getWorksid());
            if (score != null) {  // 如果找到了对应的评分
                Worksinfo worksinfo = new Worksinfo(work, score);
                worksinfos.add(worksinfo);
            }
        }

        // 格式化日期字段
        ObjectMapper objectMapper = new ObjectMapper();
        // 如果你使用的是 Java 8+ 和 Jackson 2.9+，推荐使用 JavaTimeModule
        objectMapper.registerModule(new JavaTimeModule());
        // 如果你需要自定义日期格式，可以设置 SimpleDateFormat
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));

        // 将数据转换成 JSON 格式并返回
        try (PrintWriter out = res.getWriter()) {
            String jsonResponse = objectMapper.writeValueAsString(worksinfos);
            out.write(jsonResponse);
            out.flush();
        }
    }
    //获取关注信息
    private void findAttention(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException {
        res.setContentType("application/json; charset=UTF-8");
        // 获取请求参数并验证
        String worksidParam = req.getParameter("worksid");
        if (worksidParam == null || worksidParam.isEmpty()) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"error\": \"Missing or invalid 'worksid' parameter.\"}");
            return;
        }

        int idParam;
        try {
            idParam = Integer.parseInt(worksidParam);
        } catch (NumberFormatException e) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"error\": \"Invalid 'worksid' parameter format.\"}");
            return;
        }
        // 查询关注数量
        long attentionCount = worksDao.Findattentionall(idParam);
        // 如果关注数量为 0，返回 404 Not Found
        if (attentionCount == 0) {
            res.setStatus(HttpServletResponse.SC_NOT_FOUND);
            res.getWriter().write("{\"error\": \"No attention found for the given worksid.\"}");
            return;
        }
        // 将结果转换为 JSON 格式
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonResponse = objectMapper.writeValueAsString(attentionCount);
        // 调试：打印响应内容，确保格式正确
        System.out.println("JSON Response: " + jsonResponse);
        // 构造响应结果并写入响应
        res.setStatus(HttpServletResponse.SC_OK);
        res.getWriter().write(jsonResponse);
    }
    //获取用户关注状态
    private void findAttentionuser(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException {
        res.setContentType("application/json; charset=UTF-8");
        // 获取请求参数并验证
        String worksidParam = req.getParameter("worksid");
        String useridParam = req.getParameter("userid");

        if (worksidParam == null || useridParam == null) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"success\": false, \"message\": \"Missing required parameters: worksid and/or userid.\"}");
            return;
        }
        int worksid;
        int userid;
        try {
            worksid = Integer.parseInt(worksidParam);
            userid = Integer.parseInt(useridParam);
        } catch (NumberFormatException e) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"success\": false, \"message\": \"Invalid worksid or userid format.\"}");
            return;
        }
        // 查询关注状态
        long attentionCount = worksDao.Findattentionuser(worksid, userid);
        // 如果关注数量为 0，返回 404 Not Found
        if (attentionCount == 0) {
            res.setStatus(HttpServletResponse.SC_OK);  // 返回 200 OK 状态
            res.getWriter().write("{\"success\": false, \"message\": \"No attention found for the given worksid and userid.\"}");
            return;
        }
        // 如果关注存在，返回关注信息
        res.setStatus(HttpServletResponse.SC_OK);
        String jsonResponse = "{\"success\": true, \"data\": {\"worksid\": " + worksid + ", \"userid\": " + userid + ", \"attentionCount\": " + attentionCount + "}}";
        // 返回响应
        res.getWriter().write(jsonResponse);
    }
    //新增用户关注
    private void Moattentionall(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException, ParseException {
        res.setContentType("application/json; charset=UTF-8");
        // 获取请求参数
        int worksidParam = Integer.parseInt(req.getParameter("worksid"));
        int useridParam = Integer.parseInt(req.getParameter("userid"));
        String dateString = req.getParameter("date");
        System.out.println(dateString);
        System.out.println(worksidParam);
        System.out.println(useridParam);
        // 转换日期格式
        Date DateParam = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            DateParam = sdf.parse(dateString);  // 转换字符串为 Date 对象
        } catch (ParseException e) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);  // 返回 400 错误
            res.getWriter().write("{\"success\": false, \"error\": \"Invalid date format. Please use yyyy-MM-dd.\"}");
            return;
        }
        // 调用 DAO 层方法
        int result = worksDao.MOattention(worksidParam, useridParam, DateParam);
        // 根据操作结果返回响应
        if (result > 0) {
            res.setStatus(HttpServletResponse.SC_OK);
            res.getWriter().write("{\"success\": true, \"message\": \"Attention processed successfully.\"}");
        } else {
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);  // 如果数据库操作失败
            res.getWriter().write("{\"success\": false, \"message\": \"Failed to process attention.\"}");
        }
    }
    //添加浏览次数
    private void addViews(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException {
        res.setContentType("application/json; charset=UTF-8");
        // 获取请求参数并验证
        String worksidParam = req.getParameter("worksid");
        if (worksidParam == null || worksidParam.isEmpty()) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"success\": false, \"message\": \"Missing or invalid 'worksid' parameter.\"}");
            return;
        }
        int worksid;
        try {
            worksid = Integer.parseInt(worksidParam);
        } catch (NumberFormatException e) {
            res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            res.getWriter().write("{\"success\": false, \"message\": \"Invalid 'worksid' parameter format.\"}");
            return;
        }
        try {
            worksDao.addBrowse(worksid);
            res.setStatus(HttpServletResponse.SC_OK);
            res.getWriter().write("{\"success\": true, \"message\": \"Views added successfully.\"}");
            System.out.println("浏览次数增加成功");
        } catch (SQLException e) {
            res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            res.getWriter().write("{\"success\": false, \"message\": \"An error occurred while updating the views.\"}");
            System.err.println("数据库错误：" + e.getMessage());
        }
    }
    //获取作品分数（平均）
    private void findScorebyid(HttpServletRequest req, HttpServletResponse res) throws SQLException, IOException {
    res.setContentType("application/json; charset=UTF-8");

    // 获取请求参数并验证
    String worksidParam = req.getParameter("worksid");
    if (worksidParam == null || worksidParam.isEmpty()) {
        res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        res.getWriter().write("{\"success\": false, \"message\": \"worksid parameter is missing.\"}");
        return;
    }

    try {
        int worksId = Integer.parseInt(worksidParam);
        // 查询评分
        long score = worksDao.findScoreById(worksId);
        System.out.println("查询评分：" + score);

        // 返回 JSON 响应，包含评分
        res.setStatus(HttpServletResponse.SC_OK);
        res.getWriter().write("{\"success\": true, \"worksid\": " + worksId + ", \"score\": " + score + "}");
    } catch (NumberFormatException e) {
        // 参数转换错误处理
        res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        res.getWriter().write("{\"success\": false, \"message\": \"Invalid worksid format.\"}");
    } catch (SQLException e) {
        // 数据库异常处理
        res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        res.getWriter().write("{\"success\": false, \"message\": \"Database error.\"}");
    }
}
    //获取用户关注
    private void findattentionworks(HttpServletRequest req, HttpServletResponse res) throws IOException, SQLException {
    res.setContentType("application/json; charset=UTF-8"); // 设置响应内容类型
    // 获取请求参数并验证
    String useridParam = req.getParameter("userid");
    if (useridParam == null || useridParam.isEmpty()) {
        res.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 设置状态码为 400
        res.getWriter().write("{\"success\": false, \"message\": \"userid parameter is missing.\"}");
        return; // 提前返回
    }
    try {
        int userId = Integer.parseInt(useridParam);
        // 查询关注的作品数据
        List<Works> worksList = worksDao.findAttentionWorks(userId);
        // 格式化日期字段，假设你希望日期格式为 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
        // 将查询结果转换成 JSON 字符串
        String jsonResponse = objectMapper.writeValueAsString(worksList);
        // 返回 JSON 响应
        res.setStatus(HttpServletResponse.SC_OK); // 设置状态码为 200
        res.getWriter().write("{\"success\": true, \"worksList\": " + jsonResponse + "}");
    } catch (NumberFormatException e) {
        // 参数解析失败
        res.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 设置状态码为 400
        res.getWriter().write("{\"success\": false, \"message\": \"Invalid userid format.\"}");
    } catch (SQLException e) {
        // 数据库查询失败
        res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 设置状态码为 500
        res.getWriter().write("{\"success\": false, \"message\": \"Failed to retrieve works.\"}");
    } catch (IOException e) {
        // IO 异常
        res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        res.getWriter().write("{\"success\": false, \"message\": \"An error occurred while processing your request.\"}");
        e.printStackTrace();
    }
}
}